//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2021 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto/tree/main/CodeGenerator. DO NOT EDIT.

import Foundation
import SotoCore

extension AccessAnalyzer {
    // MARK: Enums

    public enum AnalyzerStatus: String, CustomStringConvertible, Codable {
        case active = "ACTIVE"
        case creating = "CREATING"
        case disabled = "DISABLED"
        case failed = "FAILED"
        public var description: String { return self.rawValue }
    }

    public enum FindingSourceType: String, CustomStringConvertible, Codable {
        case bucketAcl = "BUCKET_ACL"
        case policy = "POLICY"
        case s3AccessPoint = "S3_ACCESS_POINT"
        public var description: String { return self.rawValue }
    }

    public enum FindingStatus: String, CustomStringConvertible, Codable {
        case active = "ACTIVE"
        case archived = "ARCHIVED"
        case resolved = "RESOLVED"
        public var description: String { return self.rawValue }
    }

    public enum FindingStatusUpdate: String, CustomStringConvertible, Codable {
        case active = "ACTIVE"
        case archived = "ARCHIVED"
        public var description: String { return self.rawValue }
    }

    public enum OrderBy: String, CustomStringConvertible, Codable {
        case asc = "ASC"
        case desc = "DESC"
        public var description: String { return self.rawValue }
    }

    public enum ReasonCode: String, CustomStringConvertible, Codable {
        case awsServiceAccessDisabled = "AWS_SERVICE_ACCESS_DISABLED"
        case delegatedAdministratorDeregistered = "DELEGATED_ADMINISTRATOR_DEREGISTERED"
        case organizationDeleted = "ORGANIZATION_DELETED"
        case serviceLinkedRoleCreationFailed = "SERVICE_LINKED_ROLE_CREATION_FAILED"
        public var description: String { return self.rawValue }
    }

    public enum ResourceType: String, CustomStringConvertible, Codable {
        case awsIamRole = "AWS::IAM::Role"
        case awsKmsKey = "AWS::KMS::Key"
        case awsLambdaFunction = "AWS::Lambda::Function"
        case awsLambdaLayerversion = "AWS::Lambda::LayerVersion"
        case awsS3Bucket = "AWS::S3::Bucket"
        case awsSecretsmanagerSecret = "AWS::SecretsManager::Secret"
        case awsSqsQueue = "AWS::SQS::Queue"
        public var description: String { return self.rawValue }
    }

    public enum `Type`: String, CustomStringConvertible, Codable {
        case account = "ACCOUNT"
        case organization = "ORGANIZATION"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AnalyzedResource: AWSDecodableShape {
        /// The actions that an external principal is granted permission to use by the policy that generated the finding.
        public let actions: [String]?
        /// The time at which the resource was analyzed.
        @CustomCoding<ISO8601DateCoder>
        public var analyzedAt: Date
        /// The time at which the finding was created.
        @CustomCoding<ISO8601DateCoder>
        public var createdAt: Date
        /// An error message.
        public let error: String?
        /// Indicates whether the policy that generated the finding grants public access to the resource.
        public let isPublic: Bool
        /// The ARN of the resource that was analyzed.
        public let resourceArn: String
        /// The AWS account ID that owns the resource.
        public let resourceOwnerAccount: String
        /// The type of the resource that was analyzed.
        public let resourceType: ResourceType
        /// Indicates how the access that generated the finding is granted. This is populated for Amazon S3 bucket findings.
        public let sharedVia: [String]?
        /// The current status of the finding generated from the analyzed resource.
        public let status: FindingStatus?
        /// The time at which the finding was updated.
        @CustomCoding<ISO8601DateCoder>
        public var updatedAt: Date

        public init(actions: [String]? = nil, analyzedAt: Date, createdAt: Date, error: String? = nil, isPublic: Bool, resourceArn: String, resourceOwnerAccount: String, resourceType: ResourceType, sharedVia: [String]? = nil, status: FindingStatus? = nil, updatedAt: Date) {
            self.actions = actions
            self.analyzedAt = analyzedAt
            self.createdAt = createdAt
            self.error = error
            self.isPublic = isPublic
            self.resourceArn = resourceArn
            self.resourceOwnerAccount = resourceOwnerAccount
            self.resourceType = resourceType
            self.sharedVia = sharedVia
            self.status = status
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case actions
            case analyzedAt
            case createdAt
            case error
            case isPublic
            case resourceArn
            case resourceOwnerAccount
            case resourceType
            case sharedVia
            case status
            case updatedAt
        }
    }

    public struct AnalyzedResourceSummary: AWSDecodableShape {
        /// The ARN of the analyzed resource.
        public let resourceArn: String
        /// The AWS account ID that owns the resource.
        public let resourceOwnerAccount: String
        /// The type of resource that was analyzed.
        public let resourceType: ResourceType

        public init(resourceArn: String, resourceOwnerAccount: String, resourceType: ResourceType) {
            self.resourceArn = resourceArn
            self.resourceOwnerAccount = resourceOwnerAccount
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn
            case resourceOwnerAccount
            case resourceType
        }
    }

    public struct AnalyzerSummary: AWSDecodableShape {
        /// The ARN of the analyzer.
        public let arn: String
        /// A timestamp for the time at which the analyzer was created.
        @CustomCoding<ISO8601DateCoder>
        public var createdAt: Date
        /// The resource that was most recently analyzed by the analyzer.
        public let lastResourceAnalyzed: String?
        /// The time at which the most recently analyzed resource was analyzed.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var lastResourceAnalyzedAt: Date?
        /// The name of the analyzer.
        public let name: String
        /// The status of the analyzer. An Active analyzer successfully monitors supported resources and generates new findings. The analyzer is Disabled when a user action, such as removing trusted access for AWS IAM Access Analyzer from AWS Organizations, causes the analyzer to stop generating new findings. The status is Creating when the analyzer creation is in progress and Failed when the analyzer creation has failed.
        public let status: AnalyzerStatus
        /// The statusReason provides more details about the current status of the analyzer. For example, if the creation for the analyzer fails, a Failed status is displayed. For an analyzer with organization as the type, this failure can be due to an issue with creating the service-linked roles required in the member accounts of the AWS organization.
        public let statusReason: StatusReason?
        /// The tags added to the analyzer.
        public let tags: [String: String]?
        /// The type of analyzer, which corresponds to the zone of trust chosen for the analyzer.
        public let type: `Type`

        public init(arn: String, createdAt: Date, lastResourceAnalyzed: String? = nil, lastResourceAnalyzedAt: Date? = nil, name: String, status: AnalyzerStatus, statusReason: StatusReason? = nil, tags: [String: String]? = nil, type: `Type`) {
            self.arn = arn
            self.createdAt = createdAt
            self.lastResourceAnalyzed = lastResourceAnalyzed
            self.lastResourceAnalyzedAt = lastResourceAnalyzedAt
            self.name = name
            self.status = status
            self.statusReason = statusReason
            self.tags = tags
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn
            case createdAt
            case lastResourceAnalyzed
            case lastResourceAnalyzedAt
            case name
            case status
            case statusReason
            case tags
            case type
        }
    }

    public struct ApplyArchiveRuleRequest: AWSEncodableShape {
        /// The Amazon resource name (ARN) of the analyzer.
        public let analyzerArn: String
        /// A client token.
        public let clientToken: String?
        /// The name of the rule to apply.
        public let ruleName: String

        public init(analyzerArn: String, clientToken: String? = ApplyArchiveRuleRequest.idempotencyToken(), ruleName: String) {
            self.analyzerArn = analyzerArn
            self.clientToken = clientToken
            self.ruleName = ruleName
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerArn, name: "analyzerArn", parent: name, pattern: "^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:analyzer/.{1,255}$")
            try self.validate(self.ruleName, name: "ruleName", parent: name, max: 255)
            try self.validate(self.ruleName, name: "ruleName", parent: name, min: 1)
            try self.validate(self.ruleName, name: "ruleName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case analyzerArn
            case clientToken
            case ruleName
        }
    }

    public struct ArchiveRuleSummary: AWSDecodableShape {
        /// The time at which the archive rule was created.
        @CustomCoding<ISO8601DateCoder>
        public var createdAt: Date
        /// A filter used to define the archive rule.
        public let filter: [String: Criterion]
        /// The name of the archive rule.
        public let ruleName: String
        /// The time at which the archive rule was last updated.
        @CustomCoding<ISO8601DateCoder>
        public var updatedAt: Date

        public init(createdAt: Date, filter: [String: Criterion], ruleName: String, updatedAt: Date) {
            self.createdAt = createdAt
            self.filter = filter
            self.ruleName = ruleName
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt
            case filter
            case ruleName
            case updatedAt
        }
    }

    public struct CreateAnalyzerRequest: AWSEncodableShape {
        /// The name of the analyzer to create.
        public let analyzerName: String
        /// Specifies the archive rules to add for the analyzer. Archive rules automatically archive findings that meet the criteria you define for the rule.
        public let archiveRules: [InlineArchiveRule]?
        /// A client token.
        public let clientToken: String?
        /// The tags to apply to the analyzer.
        public let tags: [String: String]?
        /// The type of analyzer to create. Only ACCOUNT and ORGANIZATION analyzers are supported. You can create only one analyzer per account per Region. You can create up to 5 analyzers per organization per Region.
        public let type: `Type`

        public init(analyzerName: String, archiveRules: [InlineArchiveRule]? = nil, clientToken: String? = CreateAnalyzerRequest.idempotencyToken(), tags: [String: String]? = nil, type: `Type`) {
            self.analyzerName = analyzerName
            self.archiveRules = archiveRules
            self.clientToken = clientToken
            self.tags = tags
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, max: 255)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, min: 1)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
            try self.archiveRules?.forEach {
                try $0.validate(name: "\(name).archiveRules[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case analyzerName
            case archiveRules
            case clientToken
            case tags
            case type
        }
    }

    public struct CreateAnalyzerResponse: AWSDecodableShape {
        /// The ARN of the analyzer that was created by the request.
        public let arn: String?

        public init(arn: String? = nil) {
            self.arn = arn
        }

        private enum CodingKeys: String, CodingKey {
            case arn
        }
    }

    public struct CreateArchiveRuleRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "analyzerName", location: .uri(locationName: "analyzerName"))
        ]

        /// The name of the created analyzer.
        public let analyzerName: String
        /// A client token.
        public let clientToken: String?
        /// The criteria for the rule.
        public let filter: [String: Criterion]
        /// The name of the rule to create.
        public let ruleName: String

        public init(analyzerName: String, clientToken: String? = CreateArchiveRuleRequest.idempotencyToken(), filter: [String: Criterion], ruleName: String) {
            self.analyzerName = analyzerName
            self.clientToken = clientToken
            self.filter = filter
            self.ruleName = ruleName
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, max: 255)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, min: 1)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
            try self.filter.forEach {
                try $0.value.validate(name: "\(name).filter[\"\($0.key)\"]")
            }
            try self.validate(self.ruleName, name: "ruleName", parent: name, max: 255)
            try self.validate(self.ruleName, name: "ruleName", parent: name, min: 1)
            try self.validate(self.ruleName, name: "ruleName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken
            case filter
            case ruleName
        }
    }

    public struct Criterion: AWSEncodableShape & AWSDecodableShape {
        /// A "contains" operator to match for the filter used to create the rule.
        public let contains: [String]?
        /// An "equals" operator to match for the filter used to create the rule.
        public let eq: [String]?
        /// An "exists" operator to match for the filter used to create the rule.
        public let exists: Bool?
        /// A "not equals" operator to match for the filter used to create the rule.
        public let neq: [String]?

        public init(contains: [String]? = nil, eq: [String]? = nil, exists: Bool? = nil, neq: [String]? = nil) {
            self.contains = contains
            self.eq = eq
            self.exists = exists
            self.neq = neq
        }

        public func validate(name: String) throws {
            try self.validate(self.contains, name: "contains", parent: name, max: 20)
            try self.validate(self.contains, name: "contains", parent: name, min: 1)
            try self.validate(self.eq, name: "eq", parent: name, max: 20)
            try self.validate(self.eq, name: "eq", parent: name, min: 1)
            try self.validate(self.neq, name: "neq", parent: name, max: 20)
            try self.validate(self.neq, name: "neq", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case contains
            case eq
            case exists
            case neq
        }
    }

    public struct DeleteAnalyzerRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "analyzerName", location: .uri(locationName: "analyzerName")),
            AWSMemberEncoding(label: "clientToken", location: .querystring(locationName: "clientToken"))
        ]

        /// The name of the analyzer to delete.
        public let analyzerName: String
        /// A client token.
        public let clientToken: String?

        public init(analyzerName: String, clientToken: String? = DeleteAnalyzerRequest.idempotencyToken()) {
            self.analyzerName = analyzerName
            self.clientToken = clientToken
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, max: 255)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, min: 1)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteArchiveRuleRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "analyzerName", location: .uri(locationName: "analyzerName")),
            AWSMemberEncoding(label: "clientToken", location: .querystring(locationName: "clientToken")),
            AWSMemberEncoding(label: "ruleName", location: .uri(locationName: "ruleName"))
        ]

        /// The name of the analyzer that associated with the archive rule to delete.
        public let analyzerName: String
        /// A client token.
        public let clientToken: String?
        /// The name of the rule to delete.
        public let ruleName: String

        public init(analyzerName: String, clientToken: String? = DeleteArchiveRuleRequest.idempotencyToken(), ruleName: String) {
            self.analyzerName = analyzerName
            self.clientToken = clientToken
            self.ruleName = ruleName
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, max: 255)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, min: 1)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
            try self.validate(self.ruleName, name: "ruleName", parent: name, max: 255)
            try self.validate(self.ruleName, name: "ruleName", parent: name, min: 1)
            try self.validate(self.ruleName, name: "ruleName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct Finding: AWSDecodableShape {
        /// The action in the analyzed policy statement that an external principal has permission to use.
        public let action: [String]?
        /// The time at which the resource was analyzed.
        @CustomCoding<ISO8601DateCoder>
        public var analyzedAt: Date
        /// The condition in the analyzed policy statement that resulted in a finding.
        public let condition: [String: String]
        /// The time at which the finding was generated.
        @CustomCoding<ISO8601DateCoder>
        public var createdAt: Date
        /// An error.
        public let error: String?
        /// The ID of the finding.
        public let id: String
        /// Indicates whether the policy that generated the finding allows public access to the resource.
        public let isPublic: Bool?
        /// The external principal that access to a resource within the zone of trust.
        public let principal: [String: String]?
        /// The resource that an external principal has access to.
        public let resource: String?
        /// The AWS account ID that owns the resource.
        public let resourceOwnerAccount: String
        /// The type of the resource reported in the finding.
        public let resourceType: ResourceType
        /// The sources of the finding. This indicates how the access that generated the finding is granted. It is populated for Amazon S3 bucket findings.
        public let sources: [FindingSource]?
        /// The current status of the finding.
        public let status: FindingStatus
        /// The time at which the finding was updated.
        @CustomCoding<ISO8601DateCoder>
        public var updatedAt: Date

        public init(action: [String]? = nil, analyzedAt: Date, condition: [String: String], createdAt: Date, error: String? = nil, id: String, isPublic: Bool? = nil, principal: [String: String]? = nil, resource: String? = nil, resourceOwnerAccount: String, resourceType: ResourceType, sources: [FindingSource]? = nil, status: FindingStatus, updatedAt: Date) {
            self.action = action
            self.analyzedAt = analyzedAt
            self.condition = condition
            self.createdAt = createdAt
            self.error = error
            self.id = id
            self.isPublic = isPublic
            self.principal = principal
            self.resource = resource
            self.resourceOwnerAccount = resourceOwnerAccount
            self.resourceType = resourceType
            self.sources = sources
            self.status = status
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case action
            case analyzedAt
            case condition
            case createdAt
            case error
            case id
            case isPublic
            case principal
            case resource
            case resourceOwnerAccount
            case resourceType
            case sources
            case status
            case updatedAt
        }
    }

    public struct FindingSource: AWSDecodableShape {
        /// Includes details about how the access that generated the finding is granted. This is populated for Amazon S3 bucket findings.
        public let detail: FindingSourceDetail?
        /// Indicates the type of access that generated the finding.
        public let type: FindingSourceType

        public init(detail: FindingSourceDetail? = nil, type: FindingSourceType) {
            self.detail = detail
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case detail
            case type
        }
    }

    public struct FindingSourceDetail: AWSDecodableShape {
        /// The ARN of the access point that generated the finding.
        public let accessPointArn: String?

        public init(accessPointArn: String? = nil) {
            self.accessPointArn = accessPointArn
        }

        private enum CodingKeys: String, CodingKey {
            case accessPointArn
        }
    }

    public struct FindingSummary: AWSDecodableShape {
        /// The action in the analyzed policy statement that an external principal has permission to use.
        public let action: [String]?
        /// The time at which the resource-based policy that generated the finding was analyzed.
        @CustomCoding<ISO8601DateCoder>
        public var analyzedAt: Date
        /// The condition in the analyzed policy statement that resulted in a finding.
        public let condition: [String: String]
        /// The time at which the finding was created.
        @CustomCoding<ISO8601DateCoder>
        public var createdAt: Date
        /// The error that resulted in an Error finding.
        public let error: String?
        /// The ID of the finding.
        public let id: String
        /// Indicates whether the finding reports a resource that has a policy that allows public access.
        public let isPublic: Bool?
        /// The external principal that has access to a resource within the zone of trust.
        public let principal: [String: String]?
        /// The resource that the external principal has access to.
        public let resource: String?
        /// The AWS account ID that owns the resource.
        public let resourceOwnerAccount: String
        /// The type of the resource that the external principal has access to.
        public let resourceType: ResourceType
        /// The sources of the finding. This indicates how the access that generated the finding is granted. It is populated for Amazon S3 bucket findings.
        public let sources: [FindingSource]?
        /// The status of the finding.
        public let status: FindingStatus
        /// The time at which the finding was most recently updated.
        @CustomCoding<ISO8601DateCoder>
        public var updatedAt: Date

        public init(action: [String]? = nil, analyzedAt: Date, condition: [String: String], createdAt: Date, error: String? = nil, id: String, isPublic: Bool? = nil, principal: [String: String]? = nil, resource: String? = nil, resourceOwnerAccount: String, resourceType: ResourceType, sources: [FindingSource]? = nil, status: FindingStatus, updatedAt: Date) {
            self.action = action
            self.analyzedAt = analyzedAt
            self.condition = condition
            self.createdAt = createdAt
            self.error = error
            self.id = id
            self.isPublic = isPublic
            self.principal = principal
            self.resource = resource
            self.resourceOwnerAccount = resourceOwnerAccount
            self.resourceType = resourceType
            self.sources = sources
            self.status = status
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case action
            case analyzedAt
            case condition
            case createdAt
            case error
            case id
            case isPublic
            case principal
            case resource
            case resourceOwnerAccount
            case resourceType
            case sources
            case status
            case updatedAt
        }
    }

    public struct GetAnalyzedResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "analyzerArn", location: .querystring(locationName: "analyzerArn")),
            AWSMemberEncoding(label: "resourceArn", location: .querystring(locationName: "resourceArn"))
        ]

        /// The ARN of the analyzer to retrieve information from.
        public let analyzerArn: String
        /// The ARN of the resource to retrieve information about.
        public let resourceArn: String

        public init(analyzerArn: String, resourceArn: String) {
            self.analyzerArn = analyzerArn
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerArn, name: "analyzerArn", parent: name, pattern: "^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:analyzer/.{1,255}$")
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "arn:[^:]*:[^:]*:[^:]*:[^:]*:.*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetAnalyzedResourceResponse: AWSDecodableShape {
        /// An AnalyedResource object that contains information that Access Analyzer found when it analyzed the resource.
        public let resource: AnalyzedResource?

        public init(resource: AnalyzedResource? = nil) {
            self.resource = resource
        }

        private enum CodingKeys: String, CodingKey {
            case resource
        }
    }

    public struct GetAnalyzerRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "analyzerName", location: .uri(locationName: "analyzerName"))
        ]

        /// The name of the analyzer retrieved.
        public let analyzerName: String

        public init(analyzerName: String) {
            self.analyzerName = analyzerName
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, max: 255)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, min: 1)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetAnalyzerResponse: AWSDecodableShape {
        /// An AnalyzerSummary object that contains information about the analyzer.
        public let analyzer: AnalyzerSummary

        public init(analyzer: AnalyzerSummary) {
            self.analyzer = analyzer
        }

        private enum CodingKeys: String, CodingKey {
            case analyzer
        }
    }

    public struct GetArchiveRuleRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "analyzerName", location: .uri(locationName: "analyzerName")),
            AWSMemberEncoding(label: "ruleName", location: .uri(locationName: "ruleName"))
        ]

        /// The name of the analyzer to retrieve rules from.
        public let analyzerName: String
        /// The name of the rule to retrieve.
        public let ruleName: String

        public init(analyzerName: String, ruleName: String) {
            self.analyzerName = analyzerName
            self.ruleName = ruleName
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, max: 255)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, min: 1)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
            try self.validate(self.ruleName, name: "ruleName", parent: name, max: 255)
            try self.validate(self.ruleName, name: "ruleName", parent: name, min: 1)
            try self.validate(self.ruleName, name: "ruleName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetArchiveRuleResponse: AWSDecodableShape {
        public let archiveRule: ArchiveRuleSummary

        public init(archiveRule: ArchiveRuleSummary) {
            self.archiveRule = archiveRule
        }

        private enum CodingKeys: String, CodingKey {
            case archiveRule
        }
    }

    public struct GetFindingRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "analyzerArn", location: .querystring(locationName: "analyzerArn")),
            AWSMemberEncoding(label: "id", location: .uri(locationName: "id"))
        ]

        /// The ARN of the analyzer that generated the finding.
        public let analyzerArn: String
        /// The ID of the finding to retrieve.
        public let id: String

        public init(analyzerArn: String, id: String) {
            self.analyzerArn = analyzerArn
            self.id = id
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerArn, name: "analyzerArn", parent: name, pattern: "^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:analyzer/.{1,255}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetFindingResponse: AWSDecodableShape {
        /// A finding object that contains finding details.
        public let finding: Finding?

        public init(finding: Finding? = nil) {
            self.finding = finding
        }

        private enum CodingKeys: String, CodingKey {
            case finding
        }
    }

    public struct InlineArchiveRule: AWSEncodableShape {
        /// The condition and values for a criterion.
        public let filter: [String: Criterion]
        /// The name of the rule.
        public let ruleName: String

        public init(filter: [String: Criterion], ruleName: String) {
            self.filter = filter
            self.ruleName = ruleName
        }

        public func validate(name: String) throws {
            try self.filter.forEach {
                try $0.value.validate(name: "\(name).filter[\"\($0.key)\"]")
            }
            try self.validate(self.ruleName, name: "ruleName", parent: name, max: 255)
            try self.validate(self.ruleName, name: "ruleName", parent: name, min: 1)
            try self.validate(self.ruleName, name: "ruleName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case filter
            case ruleName
        }
    }

    public struct ListAnalyzedResourcesRequest: AWSEncodableShape {
        /// The ARN of the analyzer to retrieve a list of analyzed resources from.
        public let analyzerArn: String
        /// The maximum number of results to return in the response.
        public let maxResults: Int?
        /// A token used for pagination of results returned.
        public let nextToken: String?
        /// The type of resource.
        public let resourceType: ResourceType?

        public init(analyzerArn: String, maxResults: Int? = nil, nextToken: String? = nil, resourceType: ResourceType? = nil) {
            self.analyzerArn = analyzerArn
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.resourceType = resourceType
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerArn, name: "analyzerArn", parent: name, pattern: "^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:analyzer/.{1,255}$")
        }

        private enum CodingKeys: String, CodingKey {
            case analyzerArn
            case maxResults
            case nextToken
            case resourceType
        }
    }

    public struct ListAnalyzedResourcesResponse: AWSDecodableShape {
        /// A list of resources that were analyzed.
        public let analyzedResources: [AnalyzedResourceSummary]
        /// A token used for pagination of results returned.
        public let nextToken: String?

        public init(analyzedResources: [AnalyzedResourceSummary], nextToken: String? = nil) {
            self.analyzedResources = analyzedResources
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case analyzedResources
            case nextToken
        }
    }

    public struct ListAnalyzersRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring(locationName: "maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring(locationName: "nextToken")),
            AWSMemberEncoding(label: "type", location: .querystring(locationName: "type"))
        ]

        /// The maximum number of results to return in the response.
        public let maxResults: Int?
        /// A token used for pagination of results returned.
        public let nextToken: String?
        /// The type of analyzer.
        public let type: `Type`?

        public init(maxResults: Int? = nil, nextToken: String? = nil, type: `Type`? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.type = type
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListAnalyzersResponse: AWSDecodableShape {
        /// The analyzers retrieved.
        public let analyzers: [AnalyzerSummary]
        /// A token used for pagination of results returned.
        public let nextToken: String?

        public init(analyzers: [AnalyzerSummary], nextToken: String? = nil) {
            self.analyzers = analyzers
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case analyzers
            case nextToken
        }
    }

    public struct ListArchiveRulesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "analyzerName", location: .uri(locationName: "analyzerName")),
            AWSMemberEncoding(label: "maxResults", location: .querystring(locationName: "maxResults")),
            AWSMemberEncoding(label: "nextToken", location: .querystring(locationName: "nextToken"))
        ]

        /// The name of the analyzer to retrieve rules from.
        public let analyzerName: String
        /// The maximum number of results to return in the request.
        public let maxResults: Int?
        /// A token used for pagination of results returned.
        public let nextToken: String?

        public init(analyzerName: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.analyzerName = analyzerName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, max: 255)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, min: 1)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListArchiveRulesResponse: AWSDecodableShape {
        /// A list of archive rules created for the specified analyzer.
        public let archiveRules: [ArchiveRuleSummary]
        /// A token used for pagination of results returned.
        public let nextToken: String?

        public init(archiveRules: [ArchiveRuleSummary], nextToken: String? = nil) {
            self.archiveRules = archiveRules
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case archiveRules
            case nextToken
        }
    }

    public struct ListFindingsRequest: AWSEncodableShape {
        /// The ARN of the analyzer to retrieve findings from.
        public let analyzerArn: String
        /// A filter to match for the findings to return.
        public let filter: [String: Criterion]?
        /// The maximum number of results to return in the response.
        public let maxResults: Int?
        /// A token used for pagination of results returned.
        public let nextToken: String?
        /// The sort order for the findings returned.
        public let sort: SortCriteria?

        public init(analyzerArn: String, filter: [String: Criterion]? = nil, maxResults: Int? = nil, nextToken: String? = nil, sort: SortCriteria? = nil) {
            self.analyzerArn = analyzerArn
            self.filter = filter
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.sort = sort
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerArn, name: "analyzerArn", parent: name, pattern: "^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:analyzer/.{1,255}$")
            try self.filter?.forEach {
                try $0.value.validate(name: "\(name).filter[\"\($0.key)\"]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case analyzerArn
            case filter
            case maxResults
            case nextToken
            case sort
        }
    }

    public struct ListFindingsResponse: AWSDecodableShape {
        /// A list of findings retrieved from the analyzer that match the filter criteria specified, if any.
        public let findings: [FindingSummary]
        /// A token used for pagination of results returned.
        public let nextToken: String?

        public init(findings: [FindingSummary], nextToken: String? = nil) {
            self.findings = findings
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case findings
            case nextToken
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri(locationName: "resourceArn"))
        ]

        /// The ARN of the resource to retrieve tags from.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The tags that are applied to the specified resource.
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct SortCriteria: AWSEncodableShape {
        /// The name of the attribute to sort on.
        public let attributeName: String?
        /// The sort order, ascending or descending.
        public let orderBy: OrderBy?

        public init(attributeName: String? = nil, orderBy: OrderBy? = nil) {
            self.attributeName = attributeName
            self.orderBy = orderBy
        }

        private enum CodingKeys: String, CodingKey {
            case attributeName
            case orderBy
        }
    }

    public struct StartResourceScanRequest: AWSEncodableShape {
        /// The ARN of the analyzer to use to scan the policies applied to the specified resource.
        public let analyzerArn: String
        /// The ARN of the resource to scan.
        public let resourceArn: String

        public init(analyzerArn: String, resourceArn: String) {
            self.analyzerArn = analyzerArn
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerArn, name: "analyzerArn", parent: name, pattern: "^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:analyzer/.{1,255}$")
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "arn:[^:]*:[^:]*:[^:]*:[^:]*:.*$")
        }

        private enum CodingKeys: String, CodingKey {
            case analyzerArn
            case resourceArn
        }
    }

    public struct StatusReason: AWSDecodableShape {
        /// The reason code for the current status of the analyzer.
        public let code: ReasonCode

        public init(code: ReasonCode) {
            self.code = code
        }

        private enum CodingKeys: String, CodingKey {
            case code
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri(locationName: "resourceArn"))
        ]

        /// The ARN of the resource to add the tag to.
        public let resourceArn: String
        /// The tags to add to the resource.
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri(locationName: "resourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring(locationName: "tagKeys"))
        ]

        /// The ARN of the resource to remove the tag from.
        public let resourceArn: String
        /// The key for the tag to add.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateArchiveRuleRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "analyzerName", location: .uri(locationName: "analyzerName")),
            AWSMemberEncoding(label: "ruleName", location: .uri(locationName: "ruleName"))
        ]

        /// The name of the analyzer to update the archive rules for.
        public let analyzerName: String
        /// A client token.
        public let clientToken: String?
        /// A filter to match for the rules to update. Only rules that match the filter are updated.
        public let filter: [String: Criterion]
        /// The name of the rule to update.
        public let ruleName: String

        public init(analyzerName: String, clientToken: String? = UpdateArchiveRuleRequest.idempotencyToken(), filter: [String: Criterion], ruleName: String) {
            self.analyzerName = analyzerName
            self.clientToken = clientToken
            self.filter = filter
            self.ruleName = ruleName
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, max: 255)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, min: 1)
            try self.validate(self.analyzerName, name: "analyzerName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
            try self.filter.forEach {
                try $0.value.validate(name: "\(name).filter[\"\($0.key)\"]")
            }
            try self.validate(self.ruleName, name: "ruleName", parent: name, max: 255)
            try self.validate(self.ruleName, name: "ruleName", parent: name, min: 1)
            try self.validate(self.ruleName, name: "ruleName", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_.-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken
            case filter
        }
    }

    public struct UpdateFindingsRequest: AWSEncodableShape {
        /// The ARN of the analyzer that generated the findings to update.
        public let analyzerArn: String
        /// A client token.
        public let clientToken: String?
        /// The IDs of the findings to update.
        public let ids: [String]?
        /// The ARN of the resource identified in the finding.
        public let resourceArn: String?
        /// The state represents the action to take to update the finding Status. Use ARCHIVE to change an Active finding to an Archived finding. Use ACTIVE to change an Archived finding to an Active finding.
        public let status: FindingStatusUpdate

        public init(analyzerArn: String, clientToken: String? = UpdateFindingsRequest.idempotencyToken(), ids: [String]? = nil, resourceArn: String? = nil, status: FindingStatusUpdate) {
            self.analyzerArn = analyzerArn
            self.clientToken = clientToken
            self.ids = ids
            self.resourceArn = resourceArn
            self.status = status
        }

        public func validate(name: String) throws {
            try self.validate(self.analyzerArn, name: "analyzerArn", parent: name, pattern: "^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:analyzer/.{1,255}$")
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "arn:[^:]*:[^:]*:[^:]*:[^:]*:.*$")
        }

        private enum CodingKeys: String, CodingKey {
            case analyzerArn
            case clientToken
            case ids
            case resourceArn
            case status
        }
    }
}
